package ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//import java.awt.event.KeyAdapter;
//import java.awt.event.KeyEvent;
//import java.awt.event.MouseAdapter;
//import java.awt.event.MouseEvent;

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

import core.SongIndex;
import core.SongRecord;

public class SongEditor extends JPanel implements ActionListener{

	private static final long serialVersionUID = 1L;
	protected SongRecord record = null;
	private SongIndex index = null;
	
	private SongEditor() {
		super(new GridBagLayout());
        initComponents();
        setPreferredSize(new Dimension(400, 320));
        setVisible(true);
	}
	
    public SongEditor(SongIndex ind) {
    	this();
    	setName("New Song");
		index = ind;
    }
    
    public SongEditor(SongRecord sr) {
    	this();
    	setName(sr.getField(SongRecord.TITLE).toString());
    	record = sr;
    	refreshFields();
    }
    
    private void refreshFields() {
    	titleField.setText((String)record.getField(SongRecord.TITLE));
    	authorField.setText((String)record.getField(SongRecord.AUTHOR));
    	copyrightField.setText((String)record.getField(SongRecord.COPYRIGHT));
    	lyricsTextArea.setText(record.getLyrics());
    	lyricsTextArea.setCaretPosition(0);
    }
    
    // save/close action handler
    public void actionPerformed(ActionEvent e) {
    	if (e.getActionCommand().equalsIgnoreCase("save")) {
	    	if (record == null) {
	    		record = index.newRecord(titleField.getText());
	    		index.add(record);
	    	}
	    	
	    	record.setField(SongRecord.TITLE, titleField.getText());
	    	record.setField(SongRecord.AUTHOR, authorField.getText());
			record.setField(SongRecord.COPYRIGHT, copyrightField.getText());
			record.setLyrics(lyricsTextArea.getText());
			
//			System.out.println("created: " + record);
			
			refreshFields(); 	// reload the parsed lyrics
			
			setName(titleField.getText());
    	}
    	else if (e.getActionCommand().equalsIgnoreCase("close")) {
    		
    	}
    }
    
    private void initComponents() {
    	GridBagConstraints c = new GridBagConstraints();
    	
        cutItem = new JMenuItem();
        copyItem = new JMenuItem();
        pasteItem = new JMenuItem();
        titleLabel = new JLabel();
        titleField = new JTextField();
        authorLabel = new JLabel();
        authorField = new JTextField();
        copyrightLabel = new JLabel();
        copyrightField = new JTextField();
        lyricsLabel = new JLabel();
        lyricsScrollPane = new JScrollPane();
        lyricsTextArea = new LyricsTextArea();

        cutItem.setText("Cut");
        copyItem.setText("Copy");
        pasteItem.setText("Paste");
        
        /* For later releases:
        editPopupMenu = new JPopupMenu();
        editPopupMenu.add(cutItem);
        editPopupMenu.add(copyItem);
        editPopupMenu.add(pasteItem);
        lyricsTextArea.setComponentPopupMenu(editPopupMenu);
		*/
        
        titleLabel.setText("Title");
        authorLabel.setText("Author");
        copyrightLabel.setText("Copyright");
        lyricsLabel.setText("Lyrics");
        lyricsScrollPane.setViewportView(lyricsTextArea);
        
        titleField.setDragEnabled(true);
        authorField.setDragEnabled(true);
        copyrightField.setDragEnabled(true);
        lyricsTextArea.setDragEnabled(true);
        
        c.insets.left = c.insets.right = c.insets.top = 5;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridy = 0;
        c.gridx = 0; add(titleLabel, c);
        c.weightx = 0.1;
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridx = 1; add(titleField, c);
        
        c.insets.top = 2;
        c.gridwidth = 1;
        c.gridy = 1;
        c.weightx = 0;
        c.gridx = 0; add(authorLabel, c);
        c.weightx = 0.1;
        c.gridx = 1; add(authorField, c);
        
        c.weightx = 0;
        c.gridx = 2; add(copyrightLabel, c);
        c.weightx = 0.1;
        c.gridx = 3; add(copyrightField, c);
        
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridy = 3;
        c.weightx = 0;
        c.gridx = 0; add(lyricsLabel, c);
        
        c.weighty = 0.1;
        c.gridheight = 2;
        c.fill = GridBagConstraints.BOTH;
        c.insets.bottom = 5;
        c.gridx = 1; add(lyricsScrollPane, c);
        
    }
    
    private JTextField authorField;
    private JLabel authorLabel;
    private JMenuItem copyItem;
    private JTextField copyrightField;
    private JLabel copyrightLabel;
    private JMenuItem cutItem;
    //private JPopupMenu editPopupMenu;
    private JLabel lyricsLabel;
    private JScrollPane lyricsScrollPane;
    private LyricsTextArea lyricsTextArea;
    private JMenuItem pasteItem;
    private JTextField titleField;
    private JLabel titleLabel;
    
   /* public static void main(String[] args) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
			 	JFrame f = new JFrame();
			 	f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			    f.setTitle("Song Editor");
			    SongRecord sr = new SongRecord(0, new File("data/data.txt"));
			    f.getContentPane().add(new SongEditor(sr));
			    f.pack();
			    f.setVisible(true);
			}
		});
    }*/
    
}

class LyricsTextArea extends JTextArea {
	
	private static final long serialVersionUID = 1L;
	
	public LyricsTextArea() {
		super();
		setFont(new Font("Dialog", Font.PLAIN, 12));
		
		addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent e) {
				calcHighlightArea();
				repaint();
			}
		});
		/*addKeyListener(new KeyAdapter(){
			@Override
			public void keyPressed(KeyEvent e) {
				repaint();
			}
		});
		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				new Thread() {
					@Override
					public void run() {
						int delay = getCaret().getBlinkRate() / 2;
						try {
							Thread.sleep(delay);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						repaint();
					}
				}.start();
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				mousePressed(e);
			}
		});*/
	}
	
	@Override
	public void setFont(Font f) {
		super.setFont(f);
		lineHeight = getFontMetrics(f).getHeight();
	}
	
	private void calcHighlightArea() {
		String txt = getText();
		int startPos, endPos,
			pos = getCaretPosition();
		
		
		for (startPos=pos-1; startPos>0 && startPos<txt.length(); startPos--) {
			//System.out.print(txt.charAt(startPos));
			if(txt.charAt(startPos) == '[') {
				break;
			}
		}
		
		// search forward until next tag or end of file is found
		for (endPos=pos; endPos>0 && endPos<txt.length(); endPos++)
			if(txt.charAt(endPos) == '[') {
				//hLines = countRows(txt, startPos+1, endPos);
				break;
			}
		// fix endPos if out of bounds
		if (endPos>0 && endPos == txt.length())
			endPos--;
		
		hFrom = countRows(txt, 0, startPos);
		hLines = countRows(txt, startPos+1, endPos) + 
				((endPos < txt.length() && txt.charAt(endPos)=='[') ? 0 : 1);
		
//		System.out.printf("pos %d / ", pos);
//		System.out.printf("start %d end %d / ", startPos, endPos);
//		System.out.printf("from %d height %d\n", hFrom, hLines);
		
	}
	// Counts rows between positions start and end in txt
	private static int countRows(String txt, int start, int end) {
		int row = 0;
		
		for (int i=start; i<end; i++) {
			if (txt.charAt(i) == '\n')
				row++;
		}
		return row;
	}
	
	private int hFrom,  hLines, lineHeight;
	
	@Override
	protected void paintComponent(Graphics g) {
		Rectangle oldClip = g.getClipBounds();
		//System.out.println("old clip: " + g.getClip());
		//g.setClip(0, 0, getWidth(), getHeight());
		
		// first clear the clipping area, since we're setting opaque to false
		g.setColor(Color.white);
		g.fillRect(oldClip.x, oldClip.y, oldClip.width, oldClip.height);
		//g.clearRect(0, 0, getWidth(), getHeight());
		
		// set the clipping area to the entire textbox to allow us to draw the shading
		//g.setClip(new Rectangle(0, 0, getWidth(), getHeight()));
		//System.out.println("new clip: " + g.getClip());
		
		int start = lineHeight * hFrom,
			end = lineHeight * hLines;
		g.setColor(Color.lightGray);
		g.fillRect(0, start, getWidth(), end);
		
		// set the clipping area back to the original
		//g.setClip(oldClip);
		//g.setClip(new Rectangle(0, 0, getWidth(), getHeight()));
		
		// temporarily set opaque to prevent default paintComponent() 
		//  from clearing the highlighted region
		setOpaque(false);	
		super.paintComponent(g);
		setOpaque(true);
	}
}